<?php
/**
 * Created by PhpStorm.
 * User: Administratorjing
 * Date: 2018/3/28/028
 * Time: 11:12
 */

namespace app\api\service;


use app\lib\enum\ScopeEnum;
use app\lib\exception\ForbiddenException;
use app\lib\exception\TokenException;
use think\Cache;
use think\Exception;
use think\Request;

class Token
{
    /**
     * 生成token
     * @return string
     */
    public static function generateToken()
    {
        //32个字符组成一组字符串
        $randChars = getRandChar(32);
        //用三组字符串，进行md5加密
        $timestamp = $_SERVER['REQUEST_TIME_FLOAT'];
        //salt
        $salt = config('secure.token_salt');
        return md5($randChars.$timestamp.$salt);
    }

    //获取缓存
    public static function getCurrentTokenVar($key)
    {
        //获取token,从header里面拿
        $token = Request::instance()->header('token');
        //从缓存中读取
        $vars = Cache::get($token);
        if(!$vars){
            throw new TokenException();
        }else{
            if(!is_array($vars))
            {
                //如果不是数组
                $vars = json_decode($vars,true);
            }
            if(array_key_exists($key,$vars)){
                //是数组
                return $vars[$key];
            }
            else{
                throw new Exception('尝试获取的Token变量不存在');
            }
        }
    }

    public static function getCurrentUid()
    {
        //获取到uid
        $uid = self::getCurrentTokenVar('uid');
        return $uid;
    }

    /**
     * 需要用户和管理员都可以访问的权限控制
     * @return bool
     * @throws ForbiddenException
     * @throws TokenException
     */
    public static function needPrimaryScope()
    {
        $scope = self::getCurrentTokenVar('scope');
        if($scope)
        {
            if($scope>=ScopeEnum::User){
                return true;
            }else{
                throw new ForbiddenException();
            }
        }else{
            throw new TokenException();
        }
    }

    /**
     *只有用户才能访问
     * @return bool
     * @throws ForbiddenException
     * @throws TokenException
     */
    public static function needExclusiveScope()
    {
        $scope = self::getCurrentTokenVar('scope');
        if($scope)
        {
            if($scope == ScopeEnum::User){
                return true;
            }else{
                throw new ForbiddenException();
            }
        }else{
            throw new TokenException();
        }
    }

    //是否是一个合法的操作
    public static function isValidOperate($checkedUID)
    {
        if(!$checkedUID)
        {
            throw new Exception('检查UID时必须传入一个被检查的UID');
        }
        //获取当前的UID
        $currentOperateUID = self::getCurrentUid();
        if($currentOperateUID == $checkedUID){
            return true;
        }
        return false;
    }

    /**
     * API令牌验证接口的方法
     * @param $token
     * @return bool
     */
    public static function verifyToken($token){
        $exist = Cache::get($token);
        if($exist){
            return true;
        }else{
            return false;
        }
    }
}